随着前端框架的流行,Vue 和 React 被越来越多的公司和团队使用,大家今天就跟着我一起来看看 virtual DOM 作为 Vue 和 React 的核心,它到底是什么,为什么会存在 virtual DOM,以及它是如何使用的,最后给大家简单介绍一些 diff 算法的实现。下面我们开始吧~
通过今天的介绍,我们将了解以下三部分的内容,也希望大家看后有所收获~
virtual DOM 是什么,为什么会存在 virtual DOM ?
virtual DOM 如何应用,有哪些核心的 API ?
简单介绍一下 diff 算法。
virtual DOM 是什么,为什么会存在 virtual DOM?
- 用 JS 模拟 DOM 结构(不是真正的DOM);
- DOM 结构的变化,放在 JS 层来实现;
- 提高重绘性能;
简单总结一下,由于在浏览器端频繁操作 DOM 是非常耗性能的事情,为了避免这种情况,我们会使用 JS 来模拟 DOM 结构,同时,DOM 结构的变化也同样放在 JS 层操作(JS 是图灵完备语言),这就是为什么会存在 virtual DOM 的原因。
既然 DOM 结构需要用 JS 来进行模拟,那我们下面就举一个具体的例子看看究竟是如何进行模拟的呢?
1 | <ul id='list'> |
上述是一个简单的列表结构,如果要将它用进行 JS 模拟,便是下面的结果:
1 | { |
很明显,下面的对象包含了上述列表结构的全部信息,标签、属性、子节点等等,这样我们就完成了 virtual DOM 的初始工作,那么 virtual DOM 到底是怎么实现的呢,不急,我们先去看看在没有它出现之前,用 jQuery 是怎样实现的~
DEMO
需求:将下面的数据展示成表格,随便修改一个表格,表格也跟着修改;
1 | [ |
实现如下:
1 |
|
上面的代码实现逻辑比较清晰,也并不复杂,简单来说就是初次渲染,如果数据有改动,那么更新数据再次渲染,相信大家看完代码也都足够清楚。
做了足够的铺垫,下面正式的主人公要登场了,我们接着去解决上面提出的第二个问题,virtual DOM 如何应用,有哪些核心的 API ?
virtual DOM 如何应用,有哪些核心的 API ?
下面给大家介绍 snabbdom( https://github.com/snabbdom/snabbdom )github 上面关于 virtual DOM 的第三方开源库并不是很多,这也侧面反应了其实它的实现过程还是相对复杂的,之所以挑选了 snabbdom,也是因为 Vue 2.0 的 virtual DOM 就是在它的基础上实现的。

上面这张图是 github 上面 snabbdom 的官方示例,重复出现的函数我已经标红了,不难猜测,h 函数和 patch 函数也正是 snabbdom 的核心函数。
我们仿照官方示例,试图改写刚才的 DEMO,随后去浏览器中查看 DOM 元素的变化,看看是否与我们预期的相一致。
1 |
|
上面的实现过程基本与 jQuery 的相类似,只不过引用了 snabbdom 中的函数,大家可以去浏览器中观察 DOM 的变化,看看与之前的有什么不同,不同的地方也恰恰就是 virtual DOM 存在的原因。
讲了 virtual DOM 是什么,也初步体验了 virtual DOM 的实现过程,接下来,我们继续去了解 virtual DOM 中的核心算法 —— diff 算法。
简单介绍一下 diff 算法;
想提前说一点注意,diff 算法我在这里去繁就简,因为 diff 算法非常之复杂,源码量也非常之大,所以我们在这里只做最核心流程的介绍,不去关心具体的细节,如果有感兴趣的同学可以自己抽时间去研究更加深入的 diff 算法的实现。
通过上面 snabbdom 的了解,我们不难看出,patch 函数实际就是在实现 diff 算法,那么我们就抓住核心,去研究一下 patch 函数是如何实现的,也就了解了 diff 算法。
- patch(container, vnode);
- patch(vnode, newVnode);
1 | // patch(container, vnode); |
1 | // patch(vnode, newVnode); |
上面的 createElement、updateChildren 仅仅是对 DOM 元素做了最简单的对比,就像本节开始提醒到的,我们现在在了解的阶段,无需去关注细节,把握大体实现流程即可。本文没有涉及到的内容,比如节点的新增和删除、节点的重新排序、节点的样式、属性、事件绑定等内容,如果有兴趣的同学可以自己下来慢慢研究。
以上就是 virtual DOM 与 diff 算法入门介绍的全部内容了,我们从为什么会有 virtual DOM 入手,介绍了它是什么以及如何应用,同时介绍了最核心的 diff 算法,希望对大家有所帮助。